package lock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 *
 * 读写锁
 * 是一种技术： 通过ReentrantReadWriteLock类来实现。为了提高性能， Java 提供了读写锁，在读的地方使用读锁，在写的地方使用写锁，
 * 灵活控制，如果没有写锁的情况下，读是无阻塞的，在一定程度上提高了程序的执行效率。读写锁分为读锁和写锁，多个读锁不互斥，读锁与写锁互斥，这是由 jvm 自己控制的。
 *
 * 读锁（共享锁）： 允许多个线程获取读锁，同时访问同一个资源，也是一种共享锁
 * 写锁（独占锁）： 只允许一个线程获取写锁，不允许同时访问同一个资源。
 */
public class ReentrantReadWriteLockExample {
    //读写锁
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    //公共数据源
    private int sharedResource;

    //读方法
    public int read() {
        lock.readLock().lock();
        try {
           //读取数据
            System.out.println("公共数据源："+sharedResource);
            return sharedResource;
        } finally {
            lock.readLock().unlock();
        }
    }

    //写方法
    public void write(int value) {
        lock.writeLock().lock();
        try {
            //写入数据
            sharedResource = value;
            System.out.println("写入数据："+value);
        } finally {
            lock.writeLock().unlock();
        }
    }


    public static void main(String[] args) {
        ReentrantReadWriteLockExample example = new ReentrantReadWriteLockExample();

        // 创建多个读线程
        Thread reader1 = new Thread(() -> example.read());
        Thread reader2 = new Thread(() -> example.read());
        Thread reader3 = new Thread(() -> example.read());

        // 创建一个写线程
        Thread writer = new Thread(() -> example.write(42));

        // 启动线程
        reader1.start();
        reader2.start();
        reader3.start();
        writer.start();

        // 等待线程执行完毕
        try {
            reader1.join();
            reader2.join();
            reader3.join();
            writer.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 再次进行读操作
        example.read();
    }

}
